"""
Description:
Author: 月间
Date: 2024-08-13 20:28:45
LastEditTime: 2025-03-23 19:47:40
LastEditors:
"""
from advanced_alchemy.base import BigIntAuditBase
from passlib.context import CryptContext
from sqlalchemy import String, Integer, ForeignKey, Index, UniqueConstraint, BigInteger
from sqlalchemy.orm import Mapped, mapped_column, relationship

from src.core.base.orm.orm import AbstractORMModel
from .role_model import SysRole
from .post_model import SysPost
from .dept_model import SysDept
from .m2m import sys_user_role, sys_user_post
from ..config import settings

password_context = CryptContext(schemes=["bcrypt"], deprecated="auto")


# class SysUser(AbstractORMModel):
#     __tablename__ = "sys_user"
#     __table_args__ = (
#         Index("ix_sys_user_dept_id", "dept_id"),
#         Index("ix_sys_user_status", "status"),
#         Index("ix_sys_user_is_super", "is_super"),
#         Index("ix_sys_user_email", "email"),
#         Index("ix_sys_user_phone", "phone"),
#         UniqueConstraint('username', name='uq_sys_user_username_new'),
#         {"comment": "用户表"},
#     )
#     # 获取部门信息 设置删除是设置为空
#     dept_id: Mapped[int | None] = mapped_column(
#         Integer, ForeignKey("sys_dept.id", ondelete="SET NULL"), comment="部门ID"
#     )
#     username: Mapped[str] = mapped_column(
#         String(20), nullable=False, comment="用户名"
#     )
#     nickname: Mapped[str | None] = mapped_column(String(20), comment="昵称")
#     avatar: Mapped[str | None] = mapped_column(String(255), comment="昵称")
#     email: Mapped[str | None] = mapped_column(String(64), comment="昵称")
#     phone: Mapped[str | None] = mapped_column(String(11), comment="电话")
#     password: Mapped[str] = mapped_column(String(128), nullable=False, comment="密码")
#     status: Mapped[str] = mapped_column(
#         String(1), default="1", comment="帐号状态（1正常 2停用）"
#     )
#     is_super: Mapped[str] = mapped_column(
#         String(1), default="0", comment="帐号状态（0普通 1管理员）"
#     )
#     sex: Mapped[str] = mapped_column(String(1), comment="用户性别（0女 1男 2未知）")
#     login_ip: Mapped[str | None] = mapped_column(String(30), comment="最后登录时间")
#     remark: Mapped[str | None] = mapped_column(String(255), comment="描述")
#
#     # 获取角色信息
#     roles: Mapped[set[SysRole]] = relationship("SysRole", secondary=sys_user_role)
#     # 岗位信息
#     posts: Mapped[set[SysPost]] = relationship("SysPost", secondary=sys_user_post)
#     # 菜单信息
#     dept: Mapped[SysDept] = relationship()
#
#     @classmethod
#     def get_password_hash(cls, password: str) -> str:
#         return password_context.hash(password)
#
#     @classmethod
#     def validate_password(cls, password: str, hashed_password: str) -> bool:
#         """
#
#         验证原始密码是否与哈希密码一致
#         :param password: 原始密码
#         :param hashed_password: 哈希密码
#         :return:
#         """
#         return password_context.verify(password, hashed_password)
#
#     def is_super_admin(self) -> bool:
#         # 判断是否是角色key是否ROLE_ADMIN
#         role_list = [r.role_key for r in self.roles]
#         return settings.auth.SUPER_ADMIN in role_list

class SysUser(BigIntAuditBase):
    __tablename__ = "sys_user"
    __table_args__ = (
        Index("ix_sys_user_dept_id", "dept_id"),
        Index("ix_sys_user_status", "status"),
        Index("ix_sys_user_is_super", "is_super"),
        Index("ix_sys_user_email", "email"),
        Index("ix_sys_user_phone", "phone"),
        UniqueConstraint("username", name="uq_sys_user_username_new"),
        {"comment": "用户表"},
    )
    username: Mapped[str] = mapped_column(
        String(20), nullable=False, comment="用户名"
    )
    nickname: Mapped[str | None] = mapped_column(String(20), comment="昵称")
    avatar: Mapped[str | None] = mapped_column(String(255), comment="头像")
    email: Mapped[str | None] = mapped_column(String(64), comment="邮箱")
    phone: Mapped[str | None] = mapped_column(String(11), comment="电话")
    password: Mapped[str] = mapped_column(String(128), nullable=False, comment="密码")
    status: Mapped[str] = mapped_column(
        String(1), default="1", comment="帐号状态（1正常 2停用）"
    )
    is_super: Mapped[str] = mapped_column(
        String(1), default="0", comment="帐号状态（0普通 1管理员）"
    )
    sex: Mapped[str] = mapped_column(String(1), comment="用户性别（0女 1男 2未知）")
    login_ip: Mapped[str | None] = mapped_column(String(30), comment="最后登录时间")
    remark: Mapped[str | None] = mapped_column(String(255), comment="描述")
    # 获取部门信息 设置删除是设置为空
    dept_id: Mapped[int | None] = mapped_column(
        BigInteger,
        ForeignKey("sys_dept.id", ondelete="SET NULL"),
        comment="部门ID",
        nullable=True,
    )
    # 获取角色信息
    roles: Mapped[set["SysRole"]] = relationship("SysRole", secondary=sys_user_role)
    # 岗位信息
    posts: Mapped[set["SysPost"]] = relationship("SysPost", secondary=sys_user_post)
    # 菜单信息
    dept: Mapped["SysDept"] = relationship("SysDept")

    def set_attrs(self, attrs: dict):
        """
        赋值
        :param attrs:
        :return:
        """
        for key, value in attrs.items():
            if hasattr(self, key) and key != "id":
                setattr(self, key, value)

    @classmethod
    def get_password_hash(cls, password: str) -> str:
        return password_context.hash(password)

    @classmethod
    def validate_password(cls, password: str, hashed_password: str) -> bool:
        """

        验证原始密码是否与哈希密码一致
        :param password: 原始密码
        :param hashed_password: 哈希密码
        :return:
        """
        return password_context.verify(password, hashed_password)

    def is_super_admin(self) -> bool:
        # 判断是否是角色key是否ROLE_ADMIN
        role_list = [r.role_key for r in self.roles]
        return settings.auth.SUPER_ADMIN in role_list